package com.youlu.campus.admin.user.service.impl;

import com.youlu.campus.admin.base.BaseService;
import com.youlu.campus.admin.user.dto.AppUserQueryRequest;
import com.youlu.campus.admin.user.dto.AppUserResponse;
import com.youlu.campus.admin.user.dto.AppUserUpdateRequest;
import com.youlu.campus.admin.user.entity.GroupMemberPO;
import com.youlu.campus.admin.user.entity.UserInviteCountPO;
import com.youlu.campus.admin.user.entity.UserPO;
import com.youlu.campus.admin.user.service.AppUserService;
import com.youlu.campus.admin.utils.CommonUtils;
import com.youlu.campus.base.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * c端用户接口实现类
 *
 * @author: YangJ
 * @date: 2020/12/9 16:53
 */
@Slf4j
@Service("appUserService")
public class AppUserServiceImpl extends BaseService implements AppUserService {

    @Override
    public Page<AppUserResponse> userList(AppUserQueryRequest request) {
        Query query = new Query();
        boolean selected = false;
        query.addCriteria(Criteria.where("deleted").is(false));
        if (StringUtils.isNotBlank(request.getKey())) {
            String word = CommonUtils.escapeExprSpecialWord(request.getKey());
            Pattern pattern = Pattern.compile("^.*" + word + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(new Criteria().orOperator(Criteria.where("id").is(request.getKey()),
                    Criteria.where("nickName").regex(pattern)));
            selected = true;
        }
        if (StringUtils.isNotBlank(request.getUniversityName())) {
            Pattern pattern = Pattern.compile("^.*" + request.getUniversityName() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("universityName").regex(pattern));
            selected = true;
        }
        if (StringUtils.isNotBlank(request.getStatus())) {
            query.addCriteria(Criteria.where("status").is(request.getStatus()));
            selected = true;
        }
        if (Objects.nonNull(request.getStartTime()) && Objects.nonNull(request.getEndTime())) {
            Criteria criteria = new Criteria().andOperator(Criteria.where("createdTime").gte(request.getStartTime()), Criteria.where("createdTime").lte(request.getEndTime()));
            query.addCriteria(criteria);
            selected = true;
        } else if (Objects.nonNull(request.getStartTime())) {
            query.addCriteria(Criteria.where("createdTime").gte(request.getStartTime()));
            selected = true;
        } else if (Objects.nonNull(request.getEndTime())) {
            query.addCriteria(Criteria.where("createdTime").lte(request.getEndTime()));
            selected = true;
        }
        Long count;
        if (!selected) {
            count = 10000L;
        } else {
            count = mongoTemplate.count(query, UserPO.class);
        }

        if (Objects.nonNull(count) && count.compareTo(5000L) == 1) {
            count = 10000L;
        }
        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<UserPO> userList = mongoTemplate.find(query.with(pageRequest), UserPO.class);
        List<AppUserResponse> list = userList.stream().map(user -> {
            AppUserResponse response = mapperFacade.map(user, AppUserResponse.class);
            response.setGroupRole(queryGroupRole(user.getId()));
            response.setInviteCount(queryInviteCount(user.getId()));
            return response;
        }).collect(Collectors.toList());
        final Long total = count;
        return PageableExecutionUtils.getPage(list, pageRequest, () -> total);
    }

    private Long queryInviteCount(String userId) {

        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        UserInviteCountPO invite = mongoTemplate.findOne(query, UserInviteCountPO.class);
        if (invite != null) {
            return invite.getInviteCount();
        }

        return 0L;
    }

    private String queryGroupRole(String userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("user.userId").is(userId));
        GroupMemberPO memberPO = mongoTemplate.findOne(query, GroupMemberPO.class);
        if (memberPO == null) {
            return "";
        }
        if (memberPO.isCreator()) {
            return "组长";
        } else {
            return "组员";
        }
    }

    @Override
    public boolean updateStatus(AppUserUpdateRequest request) {

        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(request.getId()));
        UserPO userPO = mongoTemplate.findOne(query, UserPO.class);
        if (userPO == null) {
            throw new BusinessException("用户查询错误！");
        }
        userPO.setStatus(request.getStatus());
        mongoTemplate.save(userPO);

        return true;
    }
}
